package com.ayf.payment.game.api.service.impl;

import com.ayf.payment.game.api.dto.GameInfoGiftDTO;
import com.ayf.payment.game.api.dto.MerchantGiftLogDTO;
import com.ayf.payment.game.api.dto.PartitionDTO;
import com.ayf.payment.game.api.dto.criteria.MerchantSettleRateCustomCriteria;
import com.ayf.payment.game.api.dto.criteria.ReissueRecordCriteria;
import com.ayf.payment.game.api.entity.GameInfo;
import com.ayf.payment.game.api.entity.GameInfoGift;
import com.ayf.payment.game.api.entity.GameInfoGiftLog;
import com.ayf.payment.game.api.entity.MerchantGiftLog;
import com.ayf.payment.game.api.entity.platform.PaymentProduct;
import com.ayf.payment.game.api.mapper.GameInfoGiftMapper;
import com.ayf.payment.game.api.mapper.GameInfoMapper;
import com.ayf.payment.game.api.mapper.MerchantGiftLogMapper;
import com.ayf.payment.game.api.service.GameInfoGiftService;
import com.ayf.payment.game.api.service.MerchantSettleRateCustomService;
import com.ayf.payment.game.api.service.PartitionService;
import com.ayf.payment.game.api.service.ReissueRecordService;
import com.ayf.payment.game.api.utils.CommonResult;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class GameInfoGiftServiceImpl implements GameInfoGiftService {

    @Resource
    private GameInfoGiftMapper gameInfoGiftMapper;
    @Resource
    private MerchantGiftLogMapper merchantGiftLogMapper;
    @Resource
    private GameInfoMapper gameInfoMapper;
    @Resource
    private PartitionService partitionService;
    @Resource
    private ReissueRecordService reissueRecordService;
    @Autowired
    private MerchantSettleRateCustomService merchantSettleRateCustomService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<GameInfoGiftDTO> selectByGameInfoId(String id) {
        List<GameInfoGift> list = gameInfoGiftMapper.getGameInfoGiftListByGameInfoId(id);
        return BeanConvertUtils.convert(list, GameInfoGiftDTO.class);
    }

    @Override
    public List<GameInfoGiftLog> selectYesterdayInfo() {
        return gameInfoGiftMapper.selectYesterdayInfo();
    }

    @Override
    public void reset() {
        gameInfoGiftMapper.reset();
    }

    @Override
    public GameInfoGiftDTO getById(Integer id) {
        return BeanConvertUtils.convert(gameInfoGiftMapper.selectByPrimaryKey(id), GameInfoGiftDTO.class);
    }

    @Override
    public void giftReceive(MerchantGiftLogDTO dto) {
        GameInfoGift gift = gameInfoGiftMapper.selectByPrimaryKey(dto.getId());
        GameInfo gameInfo = gameInfoMapper.selectByPrimaryKey(gift.getGameInfoId());
        PartitionDTO partitionInfoById = partitionService.getPartitionInfoById(dto.getPartitionId());
        gameInfoGiftMapper.updateUsed(GameInfoGiftDTO.builder().id(dto.getId()).build());
        MerchantGiftLog log = MerchantGiftLog.builder()
                .gameInfoId(gameInfo.getId())
                .account(dto.getAccount())
                .amount(gift.getAmount())
                .gameInfoName(gameInfo.getGameInfoName())
                .createTimeIndex(DateUtils.dateToInteger(new Date()))
                .openId(dto.getOpenId())
                .merchantId(gameInfo.getMerchantId())
                .status(0)
                .partitionId(dto.getPartitionId())
                .partitionName(partitionInfoById.getPartitionName())
                .build();
        merchantGiftLogMapper.insertSelective(log);
        CommonResult<T> result = manualTopUp(log, partitionInfoById);
        if (result.getCode() == 200 || result.getCode() == 801) {
            log.setStatus(1);
        } else {
            try {
                String key = "GIFT_" + log.getCreateTimeIndex() + "_" + gift.getGameInfoId() + "_" + dto.getOpenId();
                String dayKey = "GIFT_DAY_ID" + log.getCreateTimeIndex() + "_" + gameInfo.getMerchantId() + "_" + dto.getOpenId();
                String accountKey = "GIFT_ACCOUNT_" + DateUtils.dateToInteger(new Date()) + "_" + gift.getGameInfoId() + "_" + dto.getAccount();
                String dayAccountKey = "GIFT_DAY_ACCOUNT_ID" + DateUtils.dateToInteger(new Date()) + "_" + gameInfo.getMerchantId() + "_" + dto.getAccount();
                revokeGiftCount(key);
                revokeGiftCount(dayKey);
                revokeGiftCount(accountKey);
                revokeGiftCount(dayAccountKey);
            } catch (Exception e) {
                LogPortal.error("{} 游戏礼包发送网关失败，回退红包累计次数异常",e,log.getId());
            }
            log.setStatus(2);
            LogPortal.error("{} 游戏礼包发送网关失败,code返回:{}，错误描述:{}", log.getId(), result.getCode(), result.getMsg());
        }
        merchantGiftLogMapper.updateByPrimaryKeySelective(MerchantGiftLog.builder().id(log.getId()).status(log.getStatus()).build());
    }

    private void revokeGiftCount(String key) {
        String giftNum = stringRedisTemplate.opsForValue().get(key);
        int num = StringUtils.isEmpty(giftNum) ? 0 : Integer.parseInt(giftNum);
        if (num > 0) {
            stringRedisTemplate.opsForValue().increment(key, -1);
        }
    }

    /**
     * 手动充值
     */
    private CommonResult<T> manualTopUp(MerchantGiftLog log, PartitionDTO partitionInfoById) {
        ReissueRecordCriteria manualCriteria = new ReissueRecordCriteria();
        manualCriteria.setOperateIp("-");
        manualCriteria.setOperatorId(0);

        manualCriteria.setManualType("");
        manualCriteria.setRechargeNumber(log.getAccount());
        manualCriteria.setRechargeAmount(log.getAmount());
        manualCriteria.setPartitionId(log.getPartitionId());
        manualCriteria.setRatId(log.getId().toString());

        manualCriteria.setMerchantId(partitionInfoById.getMerchantId());
        MerchantSettleRateCustomCriteria merchantSettleRateCustomCriteria = new MerchantSettleRateCustomCriteria();
        merchantSettleRateCustomCriteria.setMerchantId(partitionInfoById.getMerchantId());
        merchantSettleRateCustomCriteria.setStatus("ENABLE");
        List<PaymentProduct> paymentProductList = merchantSettleRateCustomService.selectAll(merchantSettleRateCustomCriteria);
        PaymentProduct paymentProduct = paymentProductList.get(0);
        manualCriteria.setChannelName(paymentProduct.getAliasName());
        manualCriteria.setCode(paymentProduct.getCode());
        manualCriteria.setRemark("游戏红包自动补发，玩家微信ID："+log.getOpenId());

        manualCriteria.setSerialNumber("G" + SnowFlakeUtils.getUniqueId());
        String reissueRecordId = reissueRecordService.manualTopUp(manualCriteria);
        return reissueRecordService.rechargeGetWay(partitionInfoById.getMerchantId(), reissueRecordId);
    }

}


